package com.vdimitr.happycube.puzzle.solution.output;

import com.vdimitr.happycube.puzzle.piece.PuzzlePiece;
import com.vdimitr.happycube.puzzle.piece.PuzzlePieceColor;
import com.vdimitr.happycube.puzzle.piece.construction.PuzzlePieceFactory;
import com.vdimitr.happycube.puzzle.solution.PuzzlePieceSolution;
import com.vdimitr.happycube.puzzle.solution.output.conversion.PuzzlePieceSolutionMatrixToStringConverter;
import com.vdimitr.happycube.puzzle.solution.output.writer.IPuzzlePieceSolutionOutputWriter;

/**
 * This class is responsible for exporting a puzzle piece solution converted to
 * string using the plugged {@link IPuzzlePieceSolutionOutputWriter}
 * 
 * @see IPuzzlePieceSolutionOutputWriter
 * @see PuzzlePieceSolutionMatrixToStringConverter
 * @see PuzzlePieceSolution
 * 
 * @author vasileios.dimitriadis
 * 
 */
public class PuzzlePieceSolutionToStringOutput implements
		IPuzzlePieceSolutionOutput {

	/**
	 * Used for creating a null puzzle piece
	 */
	private PuzzlePieceFactory puzzlePieceFactory = PuzzlePieceFactory
			.getInstance();

	/**
	 * Used for converting the puzzle piece solution to strings
	 */
	private PuzzlePieceSolutionMatrixToStringConverter converter = null;

	/**
	 * Used for exporting the puzzle piece solution
	 */
	private IPuzzlePieceSolutionOutputWriter writer = null;

	/**
	 * Constructor
	 * 
	 * @param converter
	 *            the converter to use for transforming the puzzle piece
	 *            solution to strings
	 * @param writer
	 *            the writer to use for exporting the converted puzzle piece
	 *            solution
	 */
	public PuzzlePieceSolutionToStringOutput(
			PuzzlePieceSolutionMatrixToStringConverter converter,
			IPuzzlePieceSolutionOutputWriter writer) {
		this.converter = converter;
		this.writer = writer;
	}

	public void print(PuzzlePieceSolution puzzlePieceSolution) throws Exception {
		fillEmptySpacesWithNullPuzzlePieces(puzzlePieceSolution);
		String[] output = this.converter.toString(puzzlePieceSolution
				.getMatrix());
		this.writer.writeSolution(output);
	}

	/**
	 * The puzzle piece solution matrix contains null cells. This method fills
	 * those cells with a "Null" puzzle piece which will be translated to empty
	 * spaces
	 * 
	 * @param puzzlePieceSolution
	 *            the solution to export that contains null elements in its
	 *            representation
	 */
	private void fillEmptySpacesWithNullPuzzlePieces(
			PuzzlePieceSolution puzzlePieceSolution) {
		PuzzlePiece nullPuzzlePiece = puzzlePieceFactory.createPuzzlePiece(
				PuzzlePieceColor.NULL, 1);

		PuzzlePiece[][] puzzlePieceSolutionMatrix = puzzlePieceSolution
				.getMatrix();
		for (int i = 0; i < puzzlePieceSolutionMatrix.length; i++) {
			for (int j = 0; j < puzzlePieceSolutionMatrix[i].length; j++) {
				if (puzzlePieceSolutionMatrix[i][j] == null) {
					puzzlePieceSolutionMatrix[i][j] = nullPuzzlePiece;
				}
			}
		}
	}

}
